ci: publish PR previews as real GitHub deployments - #5371
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR Analysis Report📚 Storybook PreviewView Storybook for this PR 🧪 Sandbox PreviewView Sandbox for this PR No new or modified components detected. Bundle Size SummaryNo component packages changed. Accessibility AuditStatus: No accessibility violations detected. Generated by PR Enrichment workflow | Storybook | Sandbox | View full report |
|
Direction: keep the deployment integration. Storybook and Sandbox previews should be first-class GitHub Deployments with cleanup, not links discoverable only by parsing bot comments. |
cixzhang
left a comment
There was a problem hiding this comment.
Thanks — the required_contexts and auto_inactive notes each save someone a day, and the probe table is the right evidence.
Two things before it lands.
Records are written per commit and retired per PR head. Over the last 20 closed PRs that is 150 records against 40 retirements: 110 success records keep a live link to a pr/<n>/ directory the same job just deleted.
And the manual re-deploy's always() has no equivalent of deploy-preview's verify.ready guard — the two inline copies have already drifted — so with #5519 on main its "artifacts expired, re-run CI" stop posts failure for both environments while the preview is still live.
For the retirement, does matching the description you already write feel right, or would you rather walk the PR's commits?
[Reviewed by Robohands]
| # A PR with nothing left to retire is the normal case on a rerun, | ||
| # so an empty list must not trip `set -u`. | ||
| ids=() | ||
| mapfile -t ids < <(gh api "/repos/${GITHUB_REPOSITORY}/deployments?sha=${head_sha}&environment=${environment}" --jq '.[].id' 2>/dev/null) |
There was a problem hiding this comment.
Only the head commit. Every earlier push's record stays active pointing at the directory just deleted.
| # nothing, so it cannot call a local composite action (the gh-pages push | ||
| # loop above is duplicated for the same reason). | ||
| - name: Record the preview as a GitHub deployment | ||
| if: always() |
There was a problem hiding this comment.
Hmm, always() fires on skipped and cancelled too. deploy-preview gates on verify.ready; this doesn't.
be646be to
b204b46
Compare
cixzhang
left a comment
There was a problem hiding this comment.
Thanks — both blockers are fixed. Cleanup retires every matching historical record, and an expired manual re-deploy records nothing. The shared publisher keeps the paths together. Ready.
[Reviewed by Robohands]
4479068 to
7ee68a8
Compare
Storybook and Sandbox previews were published to GitHub Pages but invisible to GitHub's deployment-aware surfaces. Teach the shared gh-pages publisher to create transient deployments for both preview URLs, record a failed publish as failure, and retire every historical record for a preview when cleanup removes it. Automatic and manual publishing now use the same implementation, while the workflows only grant the required permission and pass the trusted PR head.
7ee68a8 to
9445b3b
Compare
cixzhang
left a comment
There was a problem hiding this comment.
Thanks — the prior cleanup and expired-artifact blockers remain fixed. The rebase keeps one publisher and records only confirmed Storybook/Sandbox targets. Ready.
[Reviewed by Robohands]
Storybook and Sandbox previews are published to GitHub Pages, but GitHub only sees the bot comment that links them. Reviewers using the PR timeline or the Deployments API cannot discover either preview as a deployment.
What changes
StorybookandSandboxdeployments on the trusted PR head, but only for targets its publication result confirms are live.failure; an expired-artifact manual re-deploy stops before the publisher, so it records nothing.Preview for PR #<n>description matches a stale preview before deleting the directory. If retirement fails, the directory remains so the next cleanup retries safely.deployments: write; publishing, recording, and cleanup remain centralized in the existing publisher.Load-bearing API details
required_contexts: []prevents deployment creation from returning409 conflictwhile unrelated PR checks are still running.auto_inactive: falseprevents one PR's success from retiring every other live PR that shares theStorybookorSandboxenvironment name.transient_environment: trueidentifies these as previews that cleanup will deactivate.Test plan
pnpm vitest run .github/scripts/lib/gh-pages-publisher.test.mjs .github/scripts/visual-gate/workflow-concurrency.test.mjs --project node --maxWorkers=1— 61 passedpnpm check:repo— passedactionlint -ignore SC2129on the three changed workflows — passedpnpm exec prettier --checkon all six changed files — passedgit diff --checkand the public-repo residue guard — passed